import React, { SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
import './index.css';

interface CalendarProps{
  value?: Date;
  defaultValue?: Date;
  onChange?: (date: Date) => void;
}


function useMergeState<T>(
    defaultSaveState: T,
    props?: {
        defaultValue: T | undefined,
        value?: T,
        onChange?: (value: T) => void // 增加这里
    }
): [T, React.Dispatch<React.SetStateAction<T>>,] {
    const {
        value: propsValue,
        defaultValue,
        onChange // 增加
    } = props || {};

    const isFirstRender = useRef(true)
    const [stateValue, setStateValue] = useState<T>(() => {
        if (propsValue !== undefined) {
            return propsValue
        } else if (defaultValue !== undefined) {
            return defaultValue
        } else {
            return defaultSaveState
        }
    });

    useEffect(() => {
        if (propsValue === undefined && !isFirstRender.current) {
            setStateValue(propsValue!)
        }
        isFirstRender.current = false
    }, [propsValue])

    function isFunction (value: unknown):value is Function {
        return typeof value === 'function'
    }

    // 增加
    const setState = useCallback((value: SetStateAction<T>) => {
        let res = isFunction(value) ? value(stateValue) : value

        if (propsValue === undefined) {
            setStateValue(res)
        }
        onChange?.(res)
    }, [stateValue])

    const mergedValue = propsValue === undefined ? stateValue : propsValue
    return [
        mergedValue,
        setState
    ]
}

function Calendar(props: CalendarProps) {
  const {
    value: propsValue,
    defaultValue,
    onChange,
  } = props;

  const [mergedValue, setState] = useMergeState<Date>(new Date(), {
    value: propsValue,
    defaultValue,
    onChange
  });

  return <div>
    {mergedValue && mergedValue.toLocaleDateString()}
    <div onClick={()=> {setState(new Date('2024-5-1'))}}>2023-5-1</div>
    <div onClick={()=> {setState(new Date('2024-5-2'))}}>2023-5-2</div>
    <div onClick={()=> {setState(new Date('2024-5-3'))}}>2023-5-3</div>
  </div>
}

function App() {
    // const [value, setValue] = useState(new Date('2024-5-1'))
    // return <Calendar value={value} onChange={(date) => {
    //     console.log(date.toLocaleDateString());
    //     setValue(date)
    // }}/>
    // 非受控
    return <Calendar defaultValue={new Date('2024-5-1')} onChange={(date) => {
        console.log(date.toLocaleDateString());
    }}/>
}

export default App;
